﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.Coffee;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Localization;
using Nop.Data;


namespace Nop.Services.Coffee
{
    public partial class CoffeeService : ICoffeeService
    {

        #region fields

        private readonly IRepository<Bean> _beanRepository;
        private readonly IRepository<Blend> _blendRepository;
        private readonly IRepository<Recipe> _recipeRepository;
        private readonly IRepository<BlendBean> _blendBeanRepository;
        private readonly IRepository<RecipeBlend> _recipeBlendRepository;

        #endregion


        #region ctor

        public CoffeeService(IRepository<Bean> beanRepository,
                             IRepository<Blend> blendRepository,
                             IRepository<Recipe> recipeRepository,
                             IRepository<BlendBean> blendBeandRepository,
                             IRepository<RecipeBlend> recipeBlendRepository)
        {
            this._beanRepository = beanRepository;
            this._blendRepository = blendRepository;
            this._recipeRepository = recipeRepository;
            this._blendBeanRepository = blendBeandRepository;
            this._recipeBlendRepository = recipeBlendRepository;
        }


        #endregion


        #region Methods


        #region Bean

        public void DeactivateBean(Bean bean)
        {
            if (bean == null)
                throw new ArgumentNullException("bean");

            bean.IsActive = false;
            //delete product
            UpdateBean(bean);
        }

        public IList<Bean> GetAllBeans(bool showInactive = false)
        {
            var query = from p in _beanRepository.Table
                        orderby p.Name
                        where (showInactive || p.IsActive)
                        select p;
            var beans = query.ToList();
            return beans;
        }

        public IList<Bean> GetAllBeansNotInBlend(int blendId, bool showInactive = false)
        {
            var query = from p in _beanRepository.Table 
                        orderby p.Name
                        where !(p.BlendBeans.Any(bb => bb.BlendId == blendId))
                        where (showInactive || p.IsActive)
                        
                        select p;
            var beans = query.ToList();
            return beans;
        }

        public Bean GetBeanById(int beanId)
        {
            if (beanId == 0)
                return null;

            var bean = _beanRepository.GetById(beanId);
            return bean;
        }

        public void InsertBean(Bean bean)
        {
            if (bean == null)
                throw new ArgumentNullException("bean");

            _beanRepository.Insert(bean);
        }

        public void UpdateBean(Bean bean)
        {
            if (bean == null)
                throw new ArgumentNullException("bean");

            _beanRepository.Update(bean);
        }


        #endregion
        
        #region Blend

        public void DeactivateBlend(Blend blend)
        {
            if (blend == null)
                throw new ArgumentNullException("blend");

            blend.IsActive = false;
            //delete blend
            UpdateBlend(blend);
        }

        public IList<Blend> GetAllBlends(bool showInactive = false)
        {
            var query = from p in _blendRepository.Table
                        orderby p.Name
                        where (showInactive || p.IsActive)
                        select p;
            var blends = query.ToList();
            return blends;
        }

        public Blend GetBlendById(int blendId)
        {
            if (blendId == 0)
                return null;

            var blend = _blendRepository.GetById(blendId);
            return blend;
        }

        public void InsertBlend(Blend blend)
        {
            if (blend == null)
                throw new ArgumentNullException("blend");

            _blendRepository.Insert(blend);
        }

        public void UpdateBlend(Blend blend)
        {
            if (blend == null)
                throw new ArgumentNullException("blend");

            _blendRepository.Update(blend);
        }

        public void InsertBlendBean(BlendBean blendBean)
        {
            if (blendBean == null)
                throw new ArgumentNullException("blendBean");

            _blendBeanRepository.Insert(blendBean);
        }

        public void DeleteBlendBean(BlendBean blendBean)
        {
            if (blendBean == null)
                throw new ArgumentNullException("blendBean");

            _blendBeanRepository.Delete(blendBean);
        }

        public IList<Blend> GetAllBlendsNotInRecipe(int recipeId, bool showInactive = false)
        {
            var query = from p in _blendRepository.Table
                        orderby p.Name
                        where !(p.RecipeBlends.Any(bb => bb.RecipeId == recipeId))
                        where (showInactive || p.IsActive)

                        select p;
            var blends = query.ToList();
            return blends;
        }



        #endregion
        
        #region Recipe

        public void DeactivateRecipe(Recipe recipe)
        {
            if (recipe == null)
                throw new ArgumentNullException("recipe");

            recipe.IsActive = false;
            //delete product
            UpdateRecipe(recipe);
        }

        public IList<Recipe> GetAllRecipes(bool showInactive = false)
        {
            var query = from p in _recipeRepository.Table
                        orderby p.Name
                        where (showInactive || p.IsActive)
                        select p;
            var recipes = query.ToList();
            return recipes;
        }

        public Recipe GetRecipeById(int recipeId)
        {
            if (recipeId == 0)
                return null;

            var recipe = _recipeRepository.GetById(recipeId);
            return recipe;
        }

        public void InsertRecipe(Recipe recipe)
        {
            if (recipe == null)
                throw new ArgumentNullException("recipe");

            _recipeRepository.Insert(recipe);
        }

        public void UpdateRecipe(Recipe recipe)
        {
            if (recipe == null)
                throw new ArgumentNullException("recipe");

            _recipeRepository.Update(recipe);
        }

        public void InsertRecipeBlend(RecipeBlend recipeBlend)
        {
            if (recipeBlend == null)
                throw new ArgumentNullException("blendBean");

            _recipeBlendRepository.Insert(recipeBlend);
        }

        public void DeleteRecipeBlend(RecipeBlend recipeBlend)
        {
            if (recipeBlend == null)
                throw new ArgumentNullException("RecipeBlend");

            _recipeBlendRepository.Delete(recipeBlend);
        }


        #endregion

        #region BlendBeans

        public void UpdateBlendBean(BlendBean blendBean)
        {
            if (blendBean == null)
                throw new ArgumentNullException("blendBean");

            _blendBeanRepository.Update(blendBean);
        }


        public BlendBean GetBlendBeanById(int blendBeanId)
        {
            if (blendBeanId == 0)
                return null;

            var blendBean = _blendBeanRepository.GetById(blendBeanId);
            return blendBean;
        }

        public IList<BlendBean> GetAllBlendBeansByBlendId(int blendId)
        {
            var query = from p in _blendBeanRepository.Table
                        where (p.BlendId == blendId)
                        select p;
            var blendBeans = query.ToList();
            return blendBeans;
        }

        public IList<BlendBean> GetAllBlendBeansByBeanId(int beandId)
        {
            var query = from p in _blendBeanRepository.Table
                        where (p.BeanId == beandId)
                        select p;
            var blendBeans = query.ToList();
            return blendBeans;
        }

        #endregion

        #region RecipeBlends

        public void UpdateRecipeBlend(RecipeBlend recipeBlend)
        {
            if (recipeBlend == null)
                throw new ArgumentNullException("recipeBlend");

            _recipeBlendRepository.Update(recipeBlend);
        }

        public RecipeBlend GetRecipeBlendById(int recipeBlendId)
        {
            if (recipeBlendId == 0)
                return null;

            var recipeBlend = _recipeBlendRepository.GetById(recipeBlendId);
            return recipeBlend;
        }

        public IList<RecipeBlend> GetAllRecipeBlendsByBlendId(int blendId)
        {
            var query = from p in _recipeBlendRepository.Table
                        where (p.BlendId == blendId)
                        select p;
            var recipeBlends = query.ToList();
            return recipeBlends;
        }

        public IList<RecipeBlend> GetAllRecipeBlendsByRecipeId(int recipeId)
        {
            var query = from p in _recipeBlendRepository.Table
                        where (p.RecipeId == recipeId)
                        select p;
            var recipeBlends = query.ToList();
            return recipeBlends;
        }

        #endregion


        #endregion

    }
}
